#include <iostream>
#include <mutex>
using namespace std;

class Singleton
{
public:
    static Singleton *getInstance()
    {
        if (instance == nullptr)
        {
            lock_guard<mutex> lock(mtx);
            if (instance ==nullptr)
            {
               instance = new Singleton();
            }
            
        }
        return instance;
    }

    void doSomething() {
        std::cout << "Doing something..." << std::endl;
    }

private:
    static Singleton *instance;
    static mutex mtx;

private:
    Singleton()
    {
        cout << "Singleton instance created." << endl;
    }

    Singleton(const Singleton &) = delete;
    Singleton &operator=(const Singleton &) = delete;
};

Singleton *Singleton::instance = nullptr;
mutex Singleton::mtx;

int main()
{
    Singleton* s1 = Singleton::getInstance();
    s1->doSomething();
    Singleton* s2 = Singleton::getInstance();
    s2->doSomething();

    cout << "s1 address: " << s1 << endl;
    cout << "s2 address: " << s2 << endl;
    return 0;
}